//
// Created by HP on 2022/1/31.
//

#ifndef TMC_TMC_MODEL_H
#define TMC_TMC_MODEL_H

#include "tmc_utils.h"

// libs
#include <glad//glad.h>
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <glm/glm.hpp>

// std
#include <memory>
#include <vector>

namespace tmc {
    class TmcModel {
    public:
        struct Vertex {
            glm::vec3 position{};
            glm::vec3 color{};
            glm::vec3 normal{};
            glm::vec2 uv{};

            bool operator==(const Vertex &other) const {
                return position == other.position &&
                color    == other.color           &&
                normal   == other.normal          &&
                uv       == other.uv;
            }
        };

        struct Builder {
            std::vector<Vertex> vertices{};
            std::vector<uint32_t> indices{};

            void loadModel(const std::string& filepath);
        };

        explicit TmcModel(const Builder& builder);
        ~TmcModel();

        TmcModel(const TmcModel&) = delete;
        TmcModel& operator=(const TmcModel&) = delete;

        void bind() const;
        void draw() const;


        static std::unique_ptr<TmcModel> createModelFromFile(const std::string &filepath);
    private:
        void createVertexBuffer(const std::vector<Vertex>& vertices);
        void createIndexBuffer(const std::vector<GLuint>& indices);
        void createVAO() { glGenVertexArrays(1, &VAO); }
        void recordVAO() { glBindVertexArray(VAO); }
        void stopRecord() { glBindVertexArray(0); }

        bool hasIndexBuffer = false;

        GLuint vertexBuffer{}; // vertex buffer 储存 Vertex
        GLuint vertexCount{};  // vertex 的数量
        GLuint VAO{};          // 对 vertex 操作的记录, 类似于 vulkan 的 command buffer

        GLuint indexBuffer{};  // 储存 index
        GLuint indexCount{};   // index 的数量
    };
}

#endif //TMC_TMC_MODEL_H
